#include "Stdafx.h"
#include "ShaderProgram.h"

namespace WindGE
{
	ShaderProgram::ShaderProgram()
	{
	}

	ShaderProgram::~ShaderProgram()
	{
	}

	bool ShaderProgram::attach_shader_object(RenderDevicePtr renderDevice, EShaderType type, 
		const std::string& fileName, const std::string& funcName, const std::string& profile)
	{
		ShaderObjectPtr shaderObject;
		switch (type)
		{
		case e_shader_vertex:
			shaderObject = std::make_shared<VertexShader>();
			break;
		case e_shader_hull:
			shaderObject = std::make_shared<HullShader>();
			break;
		case e_shader_domain:
			shaderObject = std::make_shared<DomainShader>();
			break;
		case e_shader_geometry:
			shaderObject = std::make_shared<GeometryShader>();
			break;
		case e_shader_pixel:
			shaderObject = std::make_shared<PixelShader>();
			break;
		}

		if (!shaderObject) return false;

		if (!shaderObject->init(renderDevice, shared_from_this(), fileName, funcName, profile)) return false;

		shader_object_mapping_.insert({ funcName, shaderObject });

		return true;
	}

	bool ShaderProgram::attach_cbuffer(const std::string& bufferName, ConstantBufferPtr cbuffer)
	{
		std::unordered_map<std::string, ConstantBufferPtr>::iterator iter = constant_buffer_mapping_.find(bufferName);
		if (iter == constant_buffer_mapping_.end())
		{
			constant_buffer_mapping_.insert({ bufferName, cbuffer });
		}
		else
		{
			constant_buffer_mapping_[bufferName] = cbuffer;
		}

		return true;
	}

	bool ShaderProgram::attach_texres(const std::string& texresName, TextureResourcePtr texres)
	{
		std::unordered_map<std::string, TextureResourcePtr>::iterator iter = texture_resource_mapping_.find(texresName);
		if (iter == texture_resource_mapping_.end())
		{
			texture_resource_mapping_.insert({ texresName, texres });
		}
		else
		{
			texture_resource_mapping_[texresName] = texres;
		}

		return true;
	}

	bool ShaderProgram::attach_texsampler(const std::string& texSamplerName, TextureSamplerPtr texSampler)
	{
		std::unordered_map<std::string, TextureSamplerPtr>::iterator iter = texture_sampler_mapping_.find(texSamplerName);
		if (iter == texture_sampler_mapping_.end())
		{
			texture_sampler_mapping_.insert({ texSamplerName, texSampler });
		}
		else
		{
			texture_sampler_mapping_[texSamplerName] = texSampler;
		}

		return true;
	}

	bool ShaderProgram::attach_viewtarget(const std::string& viewTargetName, ShaderViewTargetPtr viewTarget)
	{
		std::unordered_map<std::string, ShaderViewTargetPtr>::iterator iter = view_target_mapping_.find(viewTargetName);
		if (iter == view_target_mapping_.end())
		{
			view_target_mapping_.insert({ viewTargetName, viewTarget });
		}
		else
		{
			view_target_mapping_[viewTargetName] = viewTarget;
		}

		return true;
	}

	void ShaderProgram::bind()
	{
		for (shader_object_iter_ = shader_object_mapping_.begin(); 
			 shader_object_iter_ != shader_object_mapping_.end(); 
			 ++shader_object_iter_)
		{
			shader_object_iter_->second->bind();
		}
	}

	void ShaderProgram::unbind()
	{
		for (shader_object_iter_ = shader_object_mapping_.begin(); 
			 shader_object_iter_ != shader_object_mapping_.end(); 
			 ++shader_object_iter_)
		{
			shader_object_iter_->second->unbind();
		}
	}

}//end namespace WindGE


